package org.idea.spring.datasource.ibernate.handler;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class ResultSetHandler implements IResultSetHandler {

    private Class<?> beanClass;

    public ResultSetHandler(Class<?> beanClass) {
        this.beanClass = beanClass;
    }

    public void setBeanClass(Class<?> beanClass) {
        this.beanClass = beanClass;
    }

    public Class<?> getBeanClass() {
        return beanClass;
    }


    @Override
    public Object handleSingle(ResultSet rs) throws SQLException {
        try {
            if (!rs.next()) {
                return null;
            }
            // 用于封装数据的bean
            Object bean = beanClass.newInstance();
            ConcurrentHashMap<String, String> map = initObjColumn(beanClass);
            ResultSetMetaData meta = rs.getMetaData();
            int columnCount = meta.getColumnCount();
            for (int i = 0; i < columnCount; i++) {
                String columnName = meta.getColumnName(i + 1);
                Object columnValue = rs.getObject(columnName);
                try {
                    //属性修改器
                    PropertyDescriptor pd = new PropertyDescriptor(map.get(columnName),
                            bean.getClass());
                    Method method = pd.getWriteMethod(); //获取所有写的方法（setter）
                    method.invoke(bean, columnValue);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return bean;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            rs.close();
        }
    }


    /**
     * 扫描一个类里面的属性和@Column的值
     *
     * @param clazz
     * @return
     */
    private ConcurrentHashMap initObjColumn(Class clazz) {
        ConcurrentHashMap<String, String> map = new ConcurrentHashMap<String, String>();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            //存放相应的字段名--属性名
            map.put(field.getName(), field.getName());
        }
        return map;
    }

    /**
     * 将多个结果集转换为相应的list集合
     *
     * @param resultSets
     * @return
     * @throws SQLException
     */
    @Override
    public List<Object> handleList(ResultSet resultSets) {
        try {
            if (!resultSets.next()) {
                return null;
            }
            resultSets.last();
            int totalRows = resultSets.getRow();
            resultSets.first();
            // 用于封装数据的beanlist
            ConcurrentHashMap<String, String> map = initObjColumn(beanClass);
            List<Object> beanList = new ArrayList<Object>();
            for (int index = 0; index < totalRows; index++) {
                ResultSetMetaData meta = resultSets.getMetaData();
                int columnCount = meta.getColumnCount();
                Object bean = beanClass.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    String columnName = meta.getColumnName(i + 1);
                    Object columnValue = resultSets.getObject(columnName);
                    try {
                        //属性修改器
                        PropertyDescriptor pd = new PropertyDescriptor(map.get(columnName),
                                bean.getClass());
                        //获取所有写的方法（setter）
                        Method method = pd.getWriteMethod();
                        method.invoke(bean, columnValue);
                    } catch (Exception e) {
                        continue;
                    }
                }
                resultSets.next();
                beanList.add(bean);
            }
            resultSets.close();
            return beanList;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
